home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gs261sr1.zip / GS.C < prev    next >
C/C++ Source or Header  |  1993-05-24  |  15KB  |  510 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* gs.c */
  20. /* Driver program for Ghostscript */
  21. /* Define PROGRAM_NAME before we include std.h */
  22. #define PROGRAM_NAME gs_product
  23. #include "ctype_.h"
  24. #include "memory_.h"
  25. #include "string_.h"
  26. /* Capture stdin/out/err before gs.h redefines them. */
  27. #include <stdio.h>
  28. static FILE *real_stdin, *real_stdout, *real_stderr;
  29. static void
  30. get_real(void)
  31. {    real_stdin = stdin, real_stdout = stdout, real_stderr = stderr;
  32. }
  33. #include "ghost.h"
  34. #include "gxdevice.h"
  35. #include "gxdevmem.h"
  36. #include "stream.h"
  37. #include "alloc.h"
  38. #include "errors.h"
  39. #include "estack.h"
  40. #include "iscan.h"
  41. #include "main.h"
  42. #include "ostack.h"
  43. #include "store.h"
  44. #include "files.h"                /* requires stream.h */
  45.   
  46. #ifndef GS_LIB
  47. #  define GS_LIB "GS_LIB"
  48. #endif
  49.  
  50. #ifndef GS_OPTIONS
  51. #  define GS_OPTIONS "GS_OPTIONS"
  52. #endif
  53.  
  54. /* Library routines not declared in a standard header */
  55. extern char *getenv(P1(const char *));
  56. /* Note: sscanf incorrectly defines its first argument as char * */
  57. /* rather than const char *.  This accounts for the ugly casts below. */
  58.  
  59. /* Device procedures imported from gsdevice.c. */
  60. extern gx_device *gs_getdevice(P1(int));
  61. extern char *gs_devicename(P1(gx_device *));
  62.  
  63. /* Other imported data */
  64. extern int gs_alloc_debug;
  65. extern int gs_log_errors;
  66. extern gx_device *gx_device_list[];
  67. extern const char *gs_copyright;
  68. extern const int gs_revision;
  69. extern const long gs_revisiondate;
  70.  
  71. /*
  72.  * Help strings.  We have to break them up into parts, because
  73.  * the Watcom compiler has a limit of 510 characters for a single token.
  74.  * For PC displays, we want to limit the strings to 24 lines.
  75.  */
  76. private const char *gs_help1 = "\
  77. Usage: gs [switches] [file1.ps file2.ps ...]\n\
  78. Available devices:";
  79. private const char *gs_help2a = "\n\
  80. Most frequently used switches: (you can use # in place of =)\n\
  81.     @<file>              treat file like part of the command line\n\
  82.                            (to get around DOS command line limit)\n\
  83.     -d<name>[=<token>]   define name as token, or null if no token given\n\
  84.     -f<file>             read this file even if its name begins with - or @\n\
  85.     -g<width>x<height>   set width and height (`geometry'), in pixels\n\
  86.     -I<prefix>           add prefix to search path\n";
  87. private const char *gs_help2b = "\
  88.     -q                   `quiet' mode, suppress most messages\n\
  89.     -r<res>              set resolution, in pixels per inch\n\
  90.     -s<name>=<string>    define name as string\n\
  91.     -sDEVICE=<devname>   select initial device\n\
  92.     -sOutputFile=<file>  select output file: embed %d for page #,\n\
  93.                            - means stdout, use |command to pipe\n\
  94. `-' alone as a file name means read from stdin non-interactively.\n\
  95. For more complete information, please read the use.doc file.\n";
  96.  
  97. /* Forward references */
  98. private int swproc(P1(const char *));
  99. private void argproc(P1(const char *));
  100. private void cmdproc(P4(const char *, int, char *, int));
  101. private void print_revision(P0());
  102. private int esc_strlen(P1(const char *));
  103. private void esc_strcat(P2(char *, const char *));
  104. private void runarg(P4(const char **, const char *, const char *, int));
  105. private void run_string(P1(const char *));
  106.  
  107. /* Parameters set by swproc */
  108. private int quiet;
  109. private int batch;
  110.  
  111. main(int argc, const char *argv[])
  112. {    int argi;
  113.     char cstr[128];
  114.     get_real();
  115.     gs_init0(real_stdin, real_stdout, real_stderr, argc);
  116.        {    char *lib = getenv(GS_LIB);
  117.         if ( lib != 0 ) 
  118.            {    int len = strlen(lib);
  119.             gs_lib_env_path = gs_malloc(len + 1, 1, "GS_LIB");
  120.             strcpy(gs_lib_env_path, lib);
  121.            }
  122.        }
  123.     /* Execute files named in the command line, */
  124.     /* processing options along the way. */
  125.     /* Wait until the first file name (or the end */
  126.     /* of the line) to finish initialization. */
  127.     batch = 0;
  128.     quiet = 0;
  129.     /* If debugging is enabled, trace the device calls. */
  130. #ifdef DEBUG
  131.        {    extern gx_device *gs_trace_device(P1(gx_device *));
  132.         extern const gx_device_memory
  133.             mem_mono_device, mem_mapped2_color_device,
  134.             mem_mapped4_color_device, mem_mapped8_color_device,
  135.             mem_true16_color_device,
  136.             mem_true24_color_device, mem_true32_color_device;
  137.         static const gx_device_memory *mdevs[8] =
  138.            {    &mem_mono_device, &mem_mapped2_color_device,
  139.             &mem_mapped4_color_device, &mem_mapped8_color_device,
  140.             &mem_true16_color_device,
  141.             &mem_true24_color_device, &mem_true32_color_device,
  142.             0
  143.            };
  144.         gx_device **pdevs[3];
  145.         gx_device ***ppdev;
  146.         gx_device **pdev;
  147.         pdevs[0] = gx_device_list;
  148.         pdevs[1] = (gx_device **)mdevs;
  149.         pdevs[2] = 0;
  150.         for ( ppdev = pdevs; *ppdev != 0; ppdev++ )
  151.          for ( pdev = *ppdev; *pdev != 0; pdev++ )
  152.            {
  153. /******
  154.             gx_device *tdev;
  155.             gx_device_complete_procs(*pdev);
  156.             tdev = gs_trace_device(*pdev);
  157.             if ( tdev == 0 )
  158.                {    lprintf("Can't allocate traced device!\n");
  159.                 gs_exit(1);
  160.                }
  161.             *pdev = tdev;
  162.  ******/
  163.            }
  164.        }
  165. #endif
  166.     {    const char *opts = getenv(GS_OPTIONS);
  167.         if ( opts != 0 ) cmdproc(opts, 0, cstr, sizeof(cstr));
  168.     }
  169.     for ( argi = 1; argi < argc; argi++ )
  170.        {    const char **argp = &argv[argi];
  171.         const char *arg = *argp;
  172.         switch ( *arg )
  173.         {
  174.         case '@':
  175.             cmdproc(arg + 1, 1, cstr, sizeof(cstr));
  176.             break;
  177.         case '-':
  178.             if ( !strcmp(arg, "--") || !strcmp(arg, "-+") )
  179.             {    /* run with command line args */
  180.                 int nstrs = argc - argi - 2;
  181.                 if ( nstrs < 0 )    /* no file to run! */
  182.                 {    puts("Usage: gs ... -- file.ps arg1 ... argn");
  183.                     gs_exit(1);
  184.                 }
  185.                 runarg(argp + 1, "{userdict /ARGUMENTS [", "] put ", nstrs);
  186.                 gs_exit(0);
  187.             }
  188.             else
  189.             {    if ( swproc(arg) < 0 )
  190.                   fprintf(stdout, "Unknown switch %s - ignoring\n", arg);
  191.             }
  192.             break;
  193.         default:
  194.             argproc(arg);
  195.         }
  196.        }
  197.     gs_init2();
  198.     if ( !batch )
  199.         run_string("systemdict /start get exec");
  200.     gs_exit(0);
  201. }
  202.  
  203. /* Process switches */
  204. private int
  205. swproc(const char *arg)
  206. {    char sw = arg[1];
  207.     arg += 2;        /* skip - and letter */
  208.     switch ( sw )
  209.        {
  210.     default:
  211.         return -1;
  212.     case 0:                /* read stdin as a file */
  213.         batch = 1;
  214.         /* Set NOPAUSE so showpage won't try to read from stdin. */
  215.         swproc("-dNOPAUSE=true");
  216.         gs_init2();        /* Finish initialization */
  217.         run_string("(%stdin) (r) file cvx execute0");
  218.         break;
  219.     case 'A':            /* trace allocator */
  220.         gs_alloc_debug = 1; break;
  221.     case 'e':            /* log errors */
  222.         gs_log_errors = 1; break;
  223.     case 'E':            /* log errors */
  224.         gs_log_errors = 2; break;
  225.     case 'f':            /* run file of arbitrary name */
  226.         if ( *arg != 0 )
  227.             argproc(arg);
  228.         break;
  229.     case 'h':            /* print help */
  230.     case '?':            /* ditto */
  231.         print_revision();
  232.         fputs(gs_help1, stdout);
  233.            {    int i;
  234.             gx_device *pdev;
  235.             for ( i = 0; (pdev = gs_getdevice(i)) != 0; i++ )
  236.                 fprintf(stdout, (i & 7 ? " %s" : "\n    %s"),
  237.                     gs_devicename(pdev));
  238.            }
  239.         fputs(gs_help2a, stdout);
  240.         fputs(gs_help2b, stdout);
  241.         gs_exit(0);
  242.     case 'I':            /* specify search path */
  243.         gs_add_lib_path(arg);
  244.         break;
  245.     case 'q':            /* quiet startup */
  246.        {    ref vtrue;
  247.         quiet = 1;
  248.         gs_init1();
  249.         make_true(&vtrue);
  250.         initial_enter_name("QUIET", &vtrue);
  251.        }    break;
  252.     case 'D':            /* define name */
  253.     case 'd':
  254.     case 'S':            /* define name as string */
  255.     case 's':
  256.        {    const char *eqp = st